package com.xdtech.trans.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.groovy.reflection.handlegen;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xdtech.common.utils.DateUtil;
import com.xdtech.common.utils.EmptyUtil;
import com.xdtech.common.utils.DateUtil.DateStyle;
import com.xdtech.core.dao.BaseDao;
import com.xdtech.core.model.BaseItem;
import com.xdtech.core.orm.Page;
import com.xdtech.core.orm.utils.BeanUtils;
import com.xdtech.sys.model.User;
import com.xdtech.sys.service.UserService;
import com.xdtech.trans.dao.TransOrderDao;
import com.xdtech.trans.model.Person;
import com.xdtech.trans.model.TransAccount;
import com.xdtech.trans.model.TransOrder;
import com.xdtech.trans.model.TransOrderScan;
import com.xdtech.trans.model.TransWebSite;
import com.xdtech.trans.service.PersonService;
import com.xdtech.trans.service.PriceConfigService;
import com.xdtech.trans.service.TransAccountService;
import com.xdtech.trans.service.TransAccountTradeService;
import com.xdtech.trans.service.TransOrderScanService;
import com.xdtech.trans.service.TransOrderService;
import com.xdtech.trans.service.TransWebSiteService;
import com.xdtech.trans.util.TransConstants;
import com.xdtech.trans.vo.PriceConfigItem;
import com.xdtech.trans.vo.TransOrderItem;
import com.xdtech.trans.vo.TransOrderScanItem;
import com.xdtech.web.model.Pagination;

/**
 * 
 * @author max.zheng
 * @create 2015-05-26 21:56:45
 * @since 1.0
 * @see
 */
@Service
public class TransOrderServiceImpl implements TransOrderService {
	private Log log = LogFactory.getLog(TransOrderServiceImpl.class);
	@Autowired
	private TransOrderDao transOrderDao;
	@Autowired
	private BaseDao baseDao;
	@Autowired
	private TransWebSiteService transWebSiteService;
	@Autowired
	private TransAccountService transAccountService;
	@Autowired
	private TransAccountTradeService transAccountTradeService;
	@Autowired
	private PriceConfigService priceConfigService;
	@Autowired
	private TransOrderScanService transOrderScanService;
	@Autowired
	private PersonService personService;
	@Autowired
	private UserService userService;
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param entity
	 */
	public void save(TransOrder entity) {
		transOrderDao.save(entity);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param entity
	 */
	public void saveAll(List<TransOrder> entities) {
		transOrderDao.saveAll(entities);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param entity
	 */
	public void delete(TransOrder entity) {
		transOrderDao.delete(entity);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param id
	 */
	public void delete(Long id) {
		transOrderDao.delete(id);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param id
	 * @return
	 */
	public TransOrder get(Long id) {
		return transOrderDao.get(id);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @return
	 */
	public List<TransOrder> getAll() {
		return transOrderDao.getAll();
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param pg
	 * @param values
	 * @return
	 */
	public Map<String, Object> loadPageAndCondition(Pagination pg,
			Map<String, String> values) {
		Map<String, Object> results = new HashMap<String, Object>();
		List<Object> transOrders = null;
		long rows = 0;
		if (pg!=null) {
			Page<TransOrder> page = transOrderDao.findPage(pg,"from TransOrder order by createTime desc", values);
			transOrders = BeanUtils.copyListProperties(
					TransOrderItem.class, page.getResult());
			rows = page.getTotalItems();
		}else {
			List<TransOrder> transOrderList = transOrderDao.find("from TransOrder order by id desc", values);
			transOrders = BeanUtils.copyListProperties(
					TransOrderItem.class, transOrderList);
			rows = transOrders.size();
		}
		results.put("total", rows);
		results.put("rows", transOrders);
		return results;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param item
	 * @return
	 */
	public boolean saveOrUpdateTransOrder(TransOrderItem item) {
		TransOrder transOrder = null;
		if (item.getId()==null) {
			transOrder = new TransOrder();
		}else {
			transOrder = transOrderDao.get(item.getId());
		}
		//复制前台修改的属性
		BeanUtils.copyProperties(transOrder, item);
		TransWebSite startWebSite = transWebSiteService.get(item.getStartWebsiteId());
		transOrder.setStartWebsite(startWebSite.getName());
		TransWebSite endWebsite = transWebSiteService.get(item.getEndWebsiteId());
		transOrder.setEndWebsite(endWebsite.getName());
		transOrderDao.save(transOrder);
		return true;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param transOrderId
	 * @return
	 */
	public TransOrderItem loadTransOrderItem(Long transOrderId) {
		TransOrder transOrder = transOrderDao.get(transOrderId);
		TransOrderItem transOrderItem = TransOrderItem.createItem(transOrder);
		return transOrderItem;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param id
	 * @return
	 */
	public boolean deleteTransOrderInfo(long id) {
		delete(id);
		return true;
	}
	
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @param newIds
	 * @return
	 */
	public boolean deleteTransOrderInfo(List<Long> transOrderIds) {
		for (Long id : transOrderIds) {
			delete(id);
		}
		return true;
	}
	
	public Map<String, Object> loadPageDataByConditions(Pagination pg,
			BaseItem baseItem, String queryName) {
		Map<String, Object> results = new HashMap<String, Object>();
		Page page = baseDao.findPageByNamedQuery(pg, queryName,baseItem);
		results.put("total", page.getTotalItems());
		results.put("rows", page.getResult());
		return results;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-26 21:56:45
	 * @modified by
	 * @return
	 */
	@Override
	public List<TransOrderItem> loadItems() {
		List<TransOrder> transOrders = getAll();
		return TransOrderItem.createItems(transOrders);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-6-9下午9:55:05
	 * @modified by
	 * @param orderNo
	 * @return
	 */
	@Override
	public TransOrderItem loadTransOrderItemByOrderNo(String orderNo) {
		TransOrder transOrder = getOrderByNo(orderNo);
		return transOrder!=null?TransOrderItem.createItem(transOrder):null;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-6-10下午10:33:35
	 * @modified by
	 * @param orderNo
	 * @return
	 */
	@Override
	public TransOrder getOrderByNo(String orderNo) {
		List<TransOrder> transOrders = transOrderDao.findBy("orderNo", orderNo);
		return EmptyUtil.isNotEmpty(transOrders)?transOrders.get(0):null;
	}
	/* (非 Javadoc)
	 * checkOrders
	 * <p>对override方法的补充说明，若不需要则删除此行</p>
	 * 
	 * @param transOrderIds
	 * @return
	 * @see com.xdtech.trans.service.TransOrderService#checkOrders(java.util.List)
	 */
	@Override
	public String checkOrders(List<Long> transOrderIds,String operator,Long operatorId)
	{
		StringBuffer sb = new StringBuffer();
//		1.在审核后，如果网点对应的账户是预付款账户，则需要检查当前的合计应收费用是否小于账户的余额，若大于余额，则无法进行单据审核操作																																													
//		2.若账户余额大于应收费用，则产生一笔交易记录，交易类型为寄件																																													
//		3.若账户余额扣除应收小于警戒金额，则提醒已经小于警戒金额，请及时进行账户充值		
		TransOrder transOrder = null;
		for (Long id : transOrderIds)
		{
			transOrder = get(id);
			//大于等于2
			int rs = Integer.valueOf(transOrder.getOrderStatus());
			if (rs>=Integer.valueOf(TransConstants.ORDER_STATUS_OK)) {
				sb.append(transOrder.getOrderNo()+"单号已审核通过，无需再次审核\n");
				break;
			}
			//当前登录用户website
			TransWebSite currentWebSite = transWebSiteService.getPersonWebsite(operatorId);
			if (currentWebSite==null) {
				//当前登录人无所属网点；
				sb.append("当前登录用户所属网点未知，无法审核");
				
			}else {
				//当前登录用户账户
				TransAccount currentTransAccount = transAccountService.getPayAccountByWebsiteId(currentWebSite.getId());
				
				if (null != currentTransAccount)
				{
					//费用计算迁移到签收录入处理
//					handleLinkInfo(transOrder,operator,currentTransAccount);
					//变更状态,审核通过
					transOrder.setOrderStatus(TransConstants.ORDER_STATUS_OK);
					save(transOrder);
				}else
				{
					sb.append("当前登录网点"+currentWebSite.getName()+"无【预付款帐户】，无法审核\n");
				}
			}
			
		}
		return sb.toString();
	}
	/**
	 * 费用计算，资金变动处理
	 * @author <a href="max.zheng@zkteco.com">郑志雄</>
	 * @since 2015-7-6 上午9:42:57
	 * @param transOrder
	 */
	public void handleLinkInfo(TransOrder transOrder,String operator,TransAccount currentTransAccount2)
	{
		PriceConfigItem priceConfigItem = priceConfigService.loadFirstPriceConfigItem();
		//目的站点账户收入派件费用；
		TransWebSite endWebSite = transWebSiteService.get(transOrder.getEndWebsiteId());
		//账户
		TransAccount endTransAccount = transAccountService.getPayAccountByWebsiteId(endWebSite.getId());

		if (endTransAccount==null) {
			log.warn(endWebSite.getName()+"没有配置预收款资金账户");
			return;
		}
//		if (currentTransAccount==null) {
//			log.warn(operator+"所在网点没有配置预收款资金账户");
//			return;
//		}
		
		//获取录单时用户所在网点
		TransAccount createRecordAccount = transAccountService.getAccountByPerson(transOrder.getCreator());
		if (createRecordAccount==null) {
			log.warn(transOrder.getOrderNo()+","+transOrder.getCreator()+"订单没有配置预收款资金账户");
			return;
		}
		//判断是否到付标记
		if ("false".equals(transOrder.getArrivePay())) {
			//产生一条寄件（现付应收）    现金交易记录
			transAccountTradeService.createTransTradeRecord(createRecordAccount,transOrder.getTotal(),TransConstants.TRADE_SEND,operator,transOrder.getOrderNo(),false);
			
			if (null != priceConfigItem)
			{
				if (null != priceConfigItem.getLinkWebsiteId())
				{
					//中转网点账户
					TransAccount payTransAccount = transAccountService.get(priceConfigItem.getLinkWebsiteAccountid());
					if (payTransAccount!=null) {
						transAccountTradeService.createTransTradeRecord(payTransAccount,priceConfigItem.getLinkPrice(),"transChange",operator,transOrder.getOrderNo(),true);
					}
				}
				
				//派件金额统计
				double money = 0;
				if (transOrder.getWeight()>priceConfigItem.getFirstWeight())
				{
					money = (priceConfigItem.getDeliveryPrice()+(transOrder.getWeight()-priceConfigItem.getFirstWeight())*priceConfigItem.getAddDeliveryPrice());
				}else
				{
					money = priceConfigItem.getDeliveryPrice();
				}
				//创建交易记录		派件
				transAccountTradeService.createTransTradeRecord(endTransAccount,money,"delivery",operator,transOrder.getOrderNo(),true);
				
				//审核网点的账户即当前登录用户，产生中转支出和派件支出；
				//中转支出
				transAccountTradeService.createTransTradeRecord(createRecordAccount, -priceConfigItem.getLinkPrice(), TransConstants.TRADE_TRANSCHANGE, operator, transOrder.getOrderNo(),true);
				//派件支出
				transAccountTradeService.createTransTradeRecord(createRecordAccount, -money, TransConstants.TRADE_DELIVERY, operator, transOrder.getOrderNo(),true);
			}
		}else if ("true".equals(transOrder.getArrivePay())) {
			handlerArrivePay(transOrder, operator, createRecordAccount,
					priceConfigItem);
		}
		if (transOrder.getAgencyFund()!=null) {
			//代收货款支出
			transAccountTradeService.createTransTradeRecord(endTransAccount, -transOrder.getAgencyFund(), TransConstants.TRADE_AGENCYFUND, operator, transOrder.getOrderNo(),true);
			//代收货款收入
			transAccountTradeService.createTransTradeRecord(createRecordAccount, transOrder.getAgencyFund(), TransConstants.TRADE_AGENCYFUND, operator, transOrder.getOrderNo(),true);

		}
		
	}
	/**
	 * 到付统计
	 * @author max.zheng
	 * @create 2015-7-8下午9:57:54
	 * @modified by
	 * @param transOrder
	 * @param operator
	 * @param currentTransAccount
	 * @param priceConfigItem
	 */
	private void handlerArrivePay(TransOrder transOrder, String operator,
			TransAccount createRecordAccount, PriceConfigItem priceConfigItem) {
		TransWebSite endWebSite = transWebSiteService.get(transOrder.getEndWebsiteId());
		//账户
		TransAccount endTransAccount = transAccountService.getPayAccountByWebsiteId(endWebSite.getId());
		//到付-现金
		transAccountTradeService.createTransTradeRecord(endTransAccount, transOrder.getTotal(), TransConstants.TRADE_ARRIVE, operator, transOrder.getOrderNo(),false);
	    if (null != priceConfigItem)
		{
			if (null != priceConfigItem.getLinkWebsiteId())
			{
				//中转网点账户
				TransAccount payTransAccount = transAccountService.get(priceConfigItem.getLinkWebsiteAccountid());
				if (payTransAccount!=null) {
					transAccountTradeService.createTransTradeRecord(payTransAccount,priceConfigItem.getLinkPrice(),TransConstants.TRADE_TRANSCHANGE,operator,transOrder.getOrderNo(),true);
				}
			}
			
			//派件金额统计
			double money = 0;
			if (transOrder.getWeight()>priceConfigItem.getFirstWeight())
			{
				money = (priceConfigItem.getLinkPrice()+(transOrder.getWeight()-priceConfigItem.getFirstWeight())*priceConfigItem.getAddDeliveryPrice());
			}else
			{
				money = priceConfigItem.getDeliveryPrice();
			}
			
			if (endTransAccount!=null) {
				//创建交易记录		派件
				transAccountTradeService.createTransTradeRecord(endTransAccount,money,TransConstants.TRADE_DELIVERY,operator,transOrder.getOrderNo(),true);
			}else {
				log.warn(endWebSite.getName()+"没有配置预收款资金账户");
			}
			
			//当前审核网点寄件得到现金
			transAccountTradeService.createTransTradeRecord(createRecordAccount,transOrder.getTotal(),TransConstants.TRADE_SEND,operator,transOrder.getOrderNo(),false);
			//目的网点到付返回金额 现金
			transAccountTradeService.createTransTradeRecord(endTransAccount, -transOrder.getTotal(), TransConstants.TRADE_RETURN, operator, transOrder.getOrderNo(),false);
			//审核网点的账户即当前登录用户，产生中转支出和派件支出；
			//中转支出
			transAccountTradeService.createTransTradeRecord(createRecordAccount, -priceConfigItem.getLinkPrice(), TransConstants.TRADE_TRANSCHANGE, operator, transOrder.getOrderNo(),true);
			//派件支出
			transAccountTradeService.createTransTradeRecord(createRecordAccount, -money,TransConstants.TRADE_DELIVERY, operator, transOrder.getOrderNo(),true);
		}
	}
	/* (非 Javadoc)
	 * cancleCheckOrders
	 * <p>对override方法的补充说明，若不需要则删除此行</p>
	 * 
	 * @param transOrderIds
	 * @param name
	 * @return
	 * @see com.xdtech.trans.service.TransOrderService#cancleCheckOrders(java.util.List, java.lang.String)
	 */
	@Override
	public String cancleCheckOrders(List<Long> transOrderIds, String name,Long operatorId)
	{
		StringBuffer sb = new StringBuffer("");
		TransOrder transOrder = null;
		for (Long id : transOrderIds)
		{
			transOrder = get(id);
			if (TransConstants.ORDER_STATUS_OK.equals(transOrder.getOrderStatus())) {
				transOrder.setOrderStatus(TransConstants.ORDER_STATUS_NEW);
				save(transOrder);
			}else {
				sb.append("运单未审核，无法取消审核");
				break;
			}
			
		}
		return sb.toString();
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-6-16下午11:49:24
	 * @modified by
	 * @param orderNo
	 * @param status
	 */
	@Override
	public void updateOrderStatuByNo(String orderNo, String status) {
		TransOrder transOrder = getOrderByNo(orderNo);
		transOrder.setOrderStatus(status);
		save(transOrder);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-6-19下午11:06:39
	 * @modified by
	 * @param valueOf
	 * @param orderNo
	 * @return
	 */
	@Override
	public boolean checkIsExsit(Long id, String orderNo) {
		List<TransOrder> transOrders = transOrderDao.findByHql("from TransOrder where id!=? and orderNo=?", id,orderNo);
		return transOrders.size()>0;
	}
	/* (非 Javadoc)
	 * calculateTotal
	 * <p>对override方法的补充说明，若不需要则删除此行</p>
	 * 
	 * @param valueOf
	 * @return
	 * @see com.xdtech.trans.service.TransOrderService#calculateTotal(java.lang.Double)
	 */
	@Override
	public double calculateTotal(Double valueOf)
	{
		PriceConfigItem priceConfigItem = priceConfigService.loadFirstPriceConfigItem();
		double total = 0;
		if (valueOf<=priceConfigItem.getFirstWeight())
		{
			//小于
			total = priceConfigItem.getFirstPrice();
		}else if (valueOf>priceConfigItem.getFirstWeight())
		{
			int addWeight = (int) Math.ceil(valueOf-priceConfigItem.getFirstWeight());
			total = priceConfigItem.getFirstPrice()+(addWeight*priceConfigItem.getAddPrice());
		}
		return total;
	}
	/* (非 Javadoc)
	 * saveTransOrderWithApp
	 * <p>对override方法的补充说明，若不需要则删除此行</p>
	 * 
	 * @param transOrderItem
	 * @see com.xdtech.trans.service.TransOrderService#saveTransOrderWithApp(com.xdtech.trans.vo.TransOrderItem)
	 */
	@Override
	public String saveTransOrderWithApp(TransOrderItem transOrderItem)
	{
		TransOrder transOrder = getOrderByNo(transOrderItem.getOrderNo());
		if (null != transOrder)
		{
			return "运单号已存在";
		}else
		{
			transOrder = new TransOrder();
			//新增
			transOrder.setOrderStatus(TransConstants.ORDER_STATUS_NEW);
		}
		
		TransWebSite startWebSite = transWebSiteService.getWebsiteByName(transOrderItem.getStartWebsite().trim());
		if (startWebSite!=null) {
			transOrder.setStartWebsite(startWebSite.getName());
			transOrder.setStartWebsiteId(startWebSite.getId());
		}
		
		
		TransWebSite endWebSite = transWebSiteService.getWebsiteByName(transOrderItem.getEndWebsite().trim());
		if (endWebSite!=null) {
			transOrder.setEndWebsite(endWebSite.getName());
			transOrder.setEndWebsiteId(endWebSite.getId());
		}
		
		transOrder.setOrderNo(transOrderItem.getOrderNo());
		String receiveTime = transOrderItem.getReceiveTime();
		if (StringUtils.isBlank(receiveTime)) {
			receiveTime = DateUtil.getDate(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS);
		}
		transOrder.setReceiveTime(receiveTime);
		transOrder.setWeight(transOrderItem.getWeight());
		transOrder.setVolume(transOrderItem.getVolume());
		transOrder.setTotal(transOrderItem.getTotal());
		transOrder.setSalesman(transOrderItem.getSalesman());
		transOrder.setFreight(transOrderItem.getFreight());
		transOrder.setArrivePay(transOrderItem.getArrivePay());
		transOrder.setAgencyFund(transOrderItem.getAgencyFund());
		transOrder.setTotal(transOrderItem.getTotal());
		transOrder.setCreator(transOrderItem.getCreator());
		transOrder.setOrderForm(TransConstants.FROM_APP);
		//收款网点
//		TransWebSite payWebSite = transWebSiteService.getWebsiteByName(transOrderItem.getPayWebsite().trim());
//		if (payWebSite!=null) {
//			transOrder.setPayWebsite(payWebSite.getName());
//			transOrder.setPayWebsiteId(payWebSite.getId());
//		}
		
		transOrderDao.save(transOrder);
		//自动审核
		List<Long> transOrderIds = new ArrayList<Long>();
		transOrderIds.add(transOrder.getId());
		User user = userService.getUserByName(transOrder.getCreator());
		String rs = checkOrders(transOrderIds, transOrder.getSalesman(), user!=null?user.getId():0L);
		if (StringUtils.isBlank(rs)) {
			//产生一条寄件扫描
			TransOrderScanItem transOrderScanItem = new TransOrderScanItem();
			BeanUtils.copyProperties(transOrderScanItem, transOrder);
			transOrderScanItem.setScanType(TransConstants.SCAN_TYPE_START);
			rs = transOrderScanService.sureStartScan(transOrderScanItem);
		}else {
			log.error("app端保存运单="+transOrder.getOrderNo()+",自动寄件失败,原因="+rs);
		}
		return rs;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-7-25下午7:56:32
	 * @modified by
	 * @param transOrderScanIds
	 * @return
	 */
	@Override
	public String checkIsCanDel(List<Long> transOrderScanIds) {
		StringBuffer sb = new StringBuffer("");
		for (Long id : transOrderScanIds) {
			TransOrder transOrder = get(id);
			if (TransConstants.ORDER_STATUS_NEW.equals(transOrder.getOrderStatus())
					||TransConstants.ORDER_STATUS_NO.equals(transOrder.getOrderStatus())) {
				//只有取消审核和新增情况下，才能删除
			}else {
				sb.append("非新增和审核失败的，无法删除");
				break;
			}
		}
		return sb.toString();
	}

}
